<?php

/**
 * This file is part of the Framework03 PHP framework.
 * @author Walter Tamboer
 * @package Framework03
 */

class FW_Controller_Plugin_Manager
{
    /**
     * @var array A list with all the plugins registered to this plugin manager.
     */
    private $pluginList = array();

    /**
     * Register a plugin to this plugin manager.
     * @param FW_Controller_Plugin_Abstract $plugin The plugin that should be registered to this manager.
     * @return FW_Controller_Plugin_Manager
     */
    public function registerPlugin(FW_Controller_Plugin_Abstract $plugin)
    {
        if (array_search($plugin, $this->pluginList, true))
            throw FW_Controller_Plugin_Exception("The plugin has already been registered.");

        $this->pluginList[] = $plugin;
        return $this;
    }

    /**
     * Unregister a plugin from this plugin manager.
     * @param string|FW_Controller_Plugin_Abstract $plugin The plugin that should be unregistered from this manager.
     * @return FW_Controller_Plugin_Manager
     */
    public function unregisterPlugin($plugin)
    {
        if ($plugin instanceof FW_Controller_Plugin_Abstract)
        {
            $key = array_search($plugin, $this->pluginList, true);

            if (!$key)
                throw FW_Controller_Plugin_Exception("The plugin has not been registered.");
    
            unset($this->pluginList[$key]);
        }
        else if (is_string($plugin))
        {
            foreach ($this->pluginList as $key => $pluginObj)
            {
                $type = get_class($pluginObj);

                if ($plugin == $type)
                    unset($this->pluginList[$key]);
            }
        }
        else
            throw new FW_Controller_Plugin_Exception("Given plugin isn't a string or an instance of FW_Controller_Plugin_Abstract");

        return $this;
    }
    
    /**
     * Checks if the given plugin has been registered to this plugin manager.
     * @param string|FW_Controller_Plugin_Abstract The plugin to check on.
     * @return boolean Returns true if the given plugin has been registered; false otherwise.
     */
    public function isRegistered($plugin)
    {
        if (!is_string($plugin) && !($plugin instanceof FW_Controller_Plugin_Abstract))
            throw new FW_Controller_Plugin_Exception("Given plugin isn't a string or an instance of FW_Controller_Plugin_Abstract");

        if (!is_string($plugin))
            $plugin = get_class($plugin);

        foreach ($this->pluginList as $pluginObj)
        {
            if ($plugin === $pluginObj)
                return true;
        }
        
        return false;
    }

    /**
     * Called before a request is dispatched.
     * @param FW_Controller_Request_Abstract $request
     * @param FW_Controller_Response_Abstract $response
     */
    public function preDispatch(FW_Controller_Request_Abstract $request, FW_Controller_Response_Abstract $response)
    {
        foreach ($this->pluginList as $plugin)
            $plugin->preDispatch($request, $response);
    }

    /**
     * Called after a request has been dispatched.
     * @param FW_Controller_Request_Abstract $request
     * @param FW_Controller_Response_Abstract $response
     */
    public function postDispatch(FW_Controller_Request_Abstract $request, FW_Controller_Response_Abstract $response)
    {
        foreach ($this->pluginList as $plugin)
            $plugin->postDispatch($request, $response);
    }
}
